#include "BallSmackers.h"
#include "State_Menu.h"
#include "State_Initialize.h"
#include "TwoPlayer.h"
#include "ThreePlayer.h"
#include "FourPlayer.h"


//Zach DInput------------------------------------------------------------

extern IDirectInputDevice8		*mJoystick[2]; // This will be changed to an area later...
extern DIJOYSTATE2				js;
extern 	ID3DXSprite* mSprite;
//-----------------------------------------------------------------------

BallSmackers::BallSmackers(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP)
: D3DApp(hInstance, winCaption, devType, requestedVP)
{
	//make sure the computer has the proper hardware for our settings
	if(!checkDeviceCaps())
	{
		MessageBox(0, "checkDeviceCaps() Failed", 0, 0);
		PostQuitMessage(0);
	}

	//this creates a new class for the font class (well what will become our font class)
	mGfxStats = new GfxStats();

//	//obtain a pointer to a ID3DXSprite class, mSprite being the pointer
	HR(D3DXCreateSprite(gd3dDevice, &mSprite));

	//font declaration just cuz i didn't want a plain window
	D3DXFONT_DESC fontDesc;
	 fontDesc.Height = 80;
		fontDesc.Width = 40;
		fontDesc.Weight = FW_BOLD;
		fontDesc.MipLevels = 0;
		fontDesc.Italic = true;
		fontDesc.CharSet = DEFAULT_CHARSET;
		fontDesc.OutputPrecision = OUT_DEFAULT_PRECIS;
		fontDesc.Quality = DEFAULT_QUALITY;
		fontDesc.PitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
		_tcscpy(fontDesc.FaceName, _T("Comic Sans"));

		HR(D3DXCreateFontIndirect(gd3dDevice, &fontDesc, &mFont));
		
	//set up camera info
/*	mCameraRadius    = 10.0f;
	mCameraRotationY = 1.2 * D3DX_PI;
	mCameraHeight    = 5.0f;*/

	// Adds in Direct Sound
	sound.SetWindowHandle(mhMainWnd);
	sound.InitDirectSound();
	sound.StopMusic(BigBallsMusic);
	//load the textures for each sprite
	//this is where you would load any sprites you are using at the beginning of the game or perhaps for the whole game
	//we may want to modify this, but we will see how it goes, the 3 lines below can be deleted but i left them
	//for reference
	HR(D3DXCreateTextureFromFile(gd3dDevice, "MazeMenuTest01.png", &mBkgdTex));
	HR(D3DXCreateTextureFromFile(gd3dDevice, "BallSmackersTwoPlayerTest.png", &TwoPlayerMenuTex));
	HR(D3DXCreateTextureFromFile(gd3dDevice, "BallSmackersThreePlayerTest.png", &ThreePlayerMenuTex));
	HR(D3DXCreateTextureFromFile(gd3dDevice, "BallSmackersFourPlayerTest.png", &FourPlayerMenuTex));

	//set the centers of each object, centers are in image coordinates, so if image is 512x512, center is 256x256
	//this is setting the centers for each image, if we make a tile class, we may modify this part so it is more 
	//automated, but for now simply use the center of each sprite, again, left the lines below for reference
	mBkgdCenter = D3DXVECTOR3(640.0f, 400.0f, 0.0f);
	TwoPlayerMenuCenter = D3DXVECTOR3(640.0f, 400.0f, 0.0f);
	ThreePlayerMenuCenter = D3DXVECTOR3(640.0f, 400.0f, 0.0f);
	FourPlayerMenuCenter = D3DXVECTOR3(640.0f, 400.0f, 0.0f);

	//we call this because we want the device states to be set during construction as well as when a device is reset
	onResetDevice();


	// Adding in State Machine, This will be a copy of what Jon has done. 

	//Giving the state machine its very first state.
	//game.setState(State_Init::Instance());

	currState = State_Init::Instance();
	TwoPlayer::Instance();
	ThreePlayer::Instance();
	FourPlayer::Instance();
	GamePlay::Instance();

	//
	//State_Movie::Instance();
	//

}

BallSmackers::~BallSmackers()
{
	delete mGfxStats;	
	ReleaseCOM(mFont);
	ReleaseCOM(mSprite);
	ReleaseCOM(mBkgdTex);
}

bool BallSmackers::checkDeviceCaps()
{
	//check for shader support
	D3DCAPS9 caps;
	HR(gd3dDevice->GetDeviceCaps(&caps));

	//check for vertex and pixel shader version 2.0 support
	if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
	{
		MessageBox(0, "Your computer does not support Vertex Shader Version 2.0!", "Vertex Shader Support", 0);
		return false;
	}

	if(caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
	{
		MessageBox(0, "Your computer does not support Pixel Shader Version 2.0!", "Pixel Shader Support", 0);
		return false;
	}
	return true;
}

void BallSmackers::onLostDevice()
{
	//this is where we put any code that needs to be executed before the rendering device is reset
	mGfxStats->onLostDevice();
	HR(mFont->OnLostDevice());
	gDInput->onLostDevice();
	HR(mSprite->OnLostDevice());
}

void BallSmackers::onResetDevice()
{	
	// The aspect ratio depends on the backbuffer dimensions, which can 
	// possibly change after a reset.  So rebuild the projection matrix.
	GamePlay::Instance()->buildProjMtx();

	//call the onResetDevice of other objects
	mGfxStats->onResetDevice();
	HR(mSprite->OnResetDevice());
	HR(mFont->OnResetDevice());


}

void BallSmackers::updateScene(float dt)
{
	//this is somewhat how font is used, i will add a different function tho that is separate, but this
	//will give you a good idea if you look at the update function or display function in GfxStats
	//I will add another function to actually draw, but I wanted to try and get you a basic working bare bone
	//model so you could start looking around and see what is needed to get the window up adn then see what
	//is needed to actually add things such as sprites and what not

	//this function basically updates everything. It polls the keyboard, updates statistics and graphics, etc
	//two triangles for each sprite--two for background, two for ship, and two for each bullet.  Similarly, 4 vertices 
	//for each sprite.

	//notice how u update, then draw, order is important
	//mGfxStats->setTriCount(4 + mBulletList.size()*2);
	//mGfxStats->setVertexCount(8 + mBulletList.size()*4);
	//mGfxStats->update(dt);

	//Get snapshot of input devices
	gDInput->poll();

	//Game or message loop.
	if(currState == GamePlay::Instance())
	{
		GamePlay::Instance()->update(dt);
		
	}
	
	
		currState->Execute(gd3dApp);
	
	
}

//this function is very important, although it will change greatly for our game
void BallSmackers::drawScene()
{

 //   // Now we can clear just view-port's portion of the buffer to red...
 //  HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0));

 //   HR(gd3dDevice->BeginScene());
 //   
 //       //draw stuff here
	//	HR(mSprite->Begin(D3DXSPRITE_OBJECTSPACE | D3DXSPRITE_DONOTMODIFY_RENDERSTATE));
	//	

	//	mGfxStats->display();		

	//if (currState == State_Menu::Instance()) 
	//{
	//	drawMenuState();
	//}

	//else if (currState == TwoPlayer::Instance()) 
	//{
	//	drawTwoPlayerState();
	//}
	//else if (currState == ThreePlayer::Instance()) 
	//{
	//	drawThreePlayerState();
	//}
	//else if (currState == FourPlayer::Instance())
	//{
	//	drawFourPlayerState();
	//}

	////anything that needs to be drawn should be above this line and below the mSprite->Begin line
	//HR(mSprite->End());

	//HR(gd3dDevice->EndScene());
	//


	////present the back buffer
	//HR(gd3dDevice->Present(0, 0, 0, 0));

}

	void BallSmackers::drawMenuState()
	{
	D3DXMATRIX texScaling;
	D3DXMatrixScaling(&texScaling, 1.0f, -1.0f, 0.0f);
	HR(gd3dDevice->SetTransform(D3DTS_TEXTURE0, &texScaling));

	D3DXMATRIX T, S;
	D3DXMatrixTranslation(&T, -320.0f, -150.0f, 0.0f);
	D3DXMatrixScaling(&S, 1.0f, 1.0f, 0.0f);
	HR(mSprite->SetTransform(&(S*T)));

	HR(mSprite->Draw(mBkgdTex, 0, &mBkgdCenter, 0, D3DCOLOR_XRGB(255, 255, 255)));
	HR(mSprite->Flush());

	D3DXMatrixScaling(&texScaling, 1.0f, -1.0f, 0.0f);
	HR(gd3dDevice->SetTransform(D3DTS_TEXTURE0, &texScaling));


		mGfxStats->display();


	}
	void BallSmackers::drawTwoPlayerState()
	{

	//D3DXMATRIX texScaling;
	//D3DXMatrixScaling(&texScaling, 1.0f, -1.0f, 0.0f);
	//HR(gd3dDevice->SetTransform(D3DTS_TEXTURE0, &texScaling));

	//D3DXMATRIX T, S;
	//D3DXMatrixTranslation(&T, -260.0f, 0.0f, 0.0f);
	//D3DXMatrixScaling(&S, 0.68f, 1.0f, 0.0f);
	//HR(mSprite->SetTransform(&(S*T)));

	////draw the menu
	//HR(mSprite->Draw(TwoPlayerMenuTex, 0, &TwoPlayerMenuCenter, 0, D3DCOLOR_XRGB(255, 255, 255)));
	//HR(mSprite->Flush());

	////restore the texture coordinate scaling transform. mirror texture 
	////coordinates with respect to y-axis so the texture is mapped correctly onto the sprite
	//D3DXMatrixScaling(&texScaling, 1.0f, -1.0f, 0.0f);
	//HR(gd3dDevice->SetTransform(D3DTS_TEXTURE0, &texScaling));

	//mGfxStats->display();

	}
	/*void BallSmackers::drawThreePlayerState()
	{

	D3DXMATRIX texScaling;
	D3DXMatrixScaling(&texScaling, 1.0f, -1.0f, 0.0f);
	HR(gd3dDevice->SetTransform(D3DTS_TEXTURE0, &texScaling));

	D3DXMATRIX T, S;
	D3DXMatrixTranslation(&T, -260.0f, -140.0f, 0.0f);
	D3DXMatrixScaling(&S, 0.68f, 1.0f, 0.0f);
	HR(mSprite->SetTransform(&(S*T)));

	//draw the menu
	HR(mSprite->Draw(ThreePlayerMenuTex, 0, &ThreePlayerMenuCenter, 0, D3DCOLOR_XRGB(255, 255, 255)));
	HR(mSprite->Flush());

	//restore the texture coordinate scaling transform. mirror texture 
	//coordinates with respect to y-axis so the texture is mapped correctly onto the sprite
	D3DXMatrixScaling(&texScaling, 1.0f, -1.0f, 0.0f);
	HR(gd3dDevice->SetTransform(D3DTS_TEXTURE0, &texScaling));

	mGfxStats->display();

	}
	void BallSmackers::drawFourPlayerState()
	{
		
	D3DXMATRIX texScaling;
	D3DXMatrixScaling(&texScaling, 1.0f, -1.0f, 0.0f);
	HR(gd3dDevice->SetTransform(D3DTS_TEXTURE0, &texScaling));

	D3DXMATRIX T, S;
	D3DXMatrixTranslation(&T, -260.0f, -140.0f, 0.0f);
	D3DXMatrixScaling(&S, 0.68f, 1.0f, 0.0f);
	HR(mSprite->SetTransform(&(S*T)));

	//draw the menu
	HR(mSprite->Draw(FourPlayerMenuTex, 0, &FourPlayerMenuCenter, 0, D3DCOLOR_XRGB(255, 255, 255)));
	HR(mSprite->Flush());

	//restore the texture coordinate scaling transform. mirror texture 
	//coordinates with respect to y-axis so the texture is mapped correctly onto the sprite
	D3DXMatrixScaling(&texScaling, 1.0f, -1.0f, 0.0f);
	HR(gd3dDevice->SetTransform(D3DTS_TEXTURE0, &texScaling));

	mGfxStats->display();

	}*/

